package com.pickgliss.ui.controls
{
	import com.greensock.TweenLite;
	import com.pickgliss.events.InteractiveEvent;
	import com.pickgliss.events.ListItemEvent;
	import com.pickgliss.geom.InnerRectangle;
	import com.pickgliss.toplevel.StageReferance;
	import com.pickgliss.ui.ComponentFactory;
	import com.pickgliss.ui.ComponentSetting;
	import com.pickgliss.ui.core.Component;
	import com.pickgliss.utils.ClassUtils;
	import com.pickgliss.utils.DisplayUtils;
	import com.pickgliss.utils.ObjectUtils;
	
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;

	[Event(name="stateChange",type="com.pickgliss.events.InteractiveEvent")]
	public class ComboBox extends Component
	{
		public static const P_button:String = "button";
		
		public static const P_defaultShowState:String = "currentShowState";
		public static const P_listInnerRect:String = "listInnerRect";
		public static const P_listPanel:String = "listPanel";
		public static const P_textField:String = "textField";
		public static const P_textInnerRect:String = "textInnerRect";
		protected static const COMBOX_HIDE_STATE:int = 0;
		protected static const COMBOX_SHOW_STATE:int = 1;
		public static var HIDE:int = 0;
		public static var SHOW:int = 1;

		public function ComboBox()
		{
			super();
		}

		protected var _button:BaseButton;
		protected var _buttonStyle:String;
		protected var _comboboxZeroPos:Point;
		protected var _currentSelectedCellValue:*;
		protected var _currentSelectedIndex:int = -1;
		protected var _currentSelectedItem:*;
		/**
		 * 隐藏下拉列表
		 * 相关参数 ：
		 * 动画执行时间 ComponentSetting.COMBOBOX_HIDE_TIME
		 * 动画缓动函数 ComponentSetting.COMBOBOX_HIDE_EASE_FUNCTION
		 */
		protected var _defaultShowState:int = COMBOX_HIDE_STATE;
		protected var _listInnerRect:InnerRectangle;
		protected var _listInnerRectString:String;
		protected var _listPanel:ListPanel;
		protected var _listPanelStyle:String;
		protected var _maskExtends:int = 100;
		protected var _maskShape:Shape;
		protected var _selctedPropName:String;
		protected var _state:int;
		protected var _textField:TextField;
		protected var _textInnerRect:InnerRectangle;
		protected var _textRectString:String = "textRectString";
		protected var _textStyle:String;

		/**
		 * 
		 * @param $button 用于点击之后向下展开的按钮
		 * 
		 */		
		public function set button($button:BaseButton):void
		{
			if(_button == $button)return;
			ObjectUtils.disposeObject(_button);
			_button = $button;
			onPropertiesChanged(P_button);
		}
		
		public function get button():BaseButton{
			return _button;
		}
		/**
		 * 
		 * @param $button 用于点击之后向下展开的按钮的样式
		 * 
		 */	
		public function set buttonStyle(stylename:String):void
		{
			if(_buttonStyle == stylename)return;
			_buttonStyle = stylename;
			button = ComponentFactory.Instance.creat(_buttonStyle);
		}
		public function get currentSelectedCellValue():*
		{
			return _currentSelectedCellValue;
		}
		
		public function get currentSelectedIndex():int
		{
			return _currentSelectedIndex;
		}
		
		public function set currentSelectedIndex(val:int):void
		{
			_listPanel.list.currentSelectedIndex = val;
		}
		
		
		public function get currentSelectedItem():*
		{
			return _currentSelectedItem;
		}
		
		
		public function set defaultShowState(state:int):void
		{
			if(_defaultShowState == state)return;
			_defaultShowState = state;
			onPropertiesChanged(P_defaultShowState);
		}
		
		override public function dispose():void
		{
			if(_listPanel && _listPanel.list)_listPanel.list.removeStateListener(updateListSize);
			StageReferance.stage.removeEventListener(MouseEvent.CLICK,__onStageClick);
			StageReferance.stage.removeEventListener(MouseEvent.MOUSE_DOWN,__onStageDown);
			removeEventListener(Event.ADDED_TO_STAGE,__onAddToStage);
			if(_listPanel && _listPanel.list)_listPanel.list.removeEventListener(ListItemEvent.LIST_ITEM_CLICK,__onItemChanged);
			ObjectUtils.disposeObject(_listPanel);
			_listPanel = null;
			ObjectUtils.disposeObject(_button);
			_button = null;
			ObjectUtils.disposeObject(_textField);
			_textField = null;
			ObjectUtils.disposeObject(_maskShape);
			_maskShape = null;
			_listInnerRect = null;
			super.dispose();
		}
		public function doHide():void
		{
			if(_state == HIDE)return;
			if(_listPanel.vectorListModel.getSize() == 0)return;
			_defaultShowState = COMBOX_HIDE_STATE;
			TweenLite.killTweensOf(_listPanel);
			TweenLite.to(_listPanel,ComponentSetting.COMBOBOX_HIDE_TIME,{y:_comboboxZeroPos.y - _listPanel.height,ease:ComponentSetting.COMBOBOX_HIDE_EASE_FUNCTION,onComplete:onHideComplete});
			_state = HIDE;
		}
		/**
		 * 隐藏下拉列表
		 * 相关参数 ：
		 * 动画执行时间 ComponentSetting.COMBOBOX_SHOW_TIME
		 * 动画缓动函数 ComponentSetting.COMBOBOX_SHOW_EASE_FUNCTION
		 */		
		public function doShow():void
		{
			if(_state == SHOW)return;
			if(_listPanel.vectorListModel.getSize() == 0)return;
			onPosChanged();
			_defaultShowState = COMBOX_SHOW_STATE;
			if(_listPanel)
			{
				ComponentSetting.COMBOX_LIST_LAYER.addChild(_listPanel.asDisplayObject());
			}
			ComponentSetting.COMBOX_LIST_LAYER.addChild(_maskShape);
			TweenLite.killTweensOf(_listPanel);
			TweenLite.to(_listPanel,ComponentSetting.COMBOBOX_SHOW_TIME,{y:_comboboxZeroPos.y+_listInnerRect.para2,ease:ComponentSetting.COMBOBOX_SHOW_EASE_FUNCTION});
			_state = SHOW;
		}
		/**
		 * 
		 * @param rect 用来标识列表x,y,width,height的一个Rectangle
		 * 设置下拉列表的Rectangle
		 * 
		 */		
		public function set listInnerRect(rect:InnerRectangle):void
		{
			if(_listInnerRect != null && _listInnerRect.equals(rect))return;
			_listInnerRect = rect;
			onPropertiesChanged(P_listInnerRect);
		}
		/**
		 * 
		 * @param value 通过字符串来创建Rectangle来设置listRect
		 * 具体请看listRect
		 * 
		 */		
		public function set listInnerRectString(value:String):void
		{
			if(_listInnerRectString == value)return;
			_listInnerRectString = value;
			listInnerRect = ClassUtils.CreatInstance(ClassUtils.INNERRECTANGLE,ComponentFactory.parasArgs(_listInnerRectString));
		}
		/**
		 * 
		 * 下拉列表中的ListPanel
		 * 
		 */		
		public function get listPanel():ListPanel
		{
			return _listPanel;
		}
		public function set listPanel($list:ListPanel):void
		{
			if(_listPanel == $list)return;
			if(_listPanel)_listPanel.list.removeEventListener(ListItemEvent.LIST_ITEM_CLICK,__onItemChanged);
			ObjectUtils.disposeObject(_listPanel);
			_listPanel = $list;
			_listPanel.list.addEventListener(ListItemEvent.LIST_ITEM_CLICK,__onItemChanged);
			onPropertiesChanged(P_listPanel);
		}
		/**
		 * 
		 * @param stylename 下拉列表的的样式，通过ComponentFactory.Instance.creat来创建
		 * 
		 */		
		public function set listPanelStyle(stylename:String):void
		{
			if(_listPanelStyle == stylename)return;
			_listPanelStyle = stylename;
			listPanel = ComponentFactory.Instance.creat(_listPanelStyle);
		}
		/**
		 * 
		 * @param propname 用于显示的选中列的属性。
		 * 例如：combox.selctedPropName = "text";
		 * 那么当Combox的下拉列表选中其中的某一列时，
		 * 那么将会执行 Combox.textField.text = _list.selectedItem[_selctedPropName];
		 */		
		public function set selctedPropName(propname:String):void
		{
			if(_selctedPropName == propname)return;
			_selctedPropName = propname;
		}
		
		public function get textField():TextField
		{
			return _textField;
		}
		/**
		 * 
		 * @param field 用于显示选中信息的文本
		 * 
		 */		
		public function set textField(field:TextField):void
		{
			if(_textField == field)return;
			_textField = field;
			onPropertiesChanged(P_textField);
		}
		/**
		 * 
		 * @param rect 用于定位选中信息的文本的Rectangle的信息
		 * 
		 */		
		public function set textInnerRect(rect:InnerRectangle):void
		{
			if(_textInnerRect != null && _textInnerRect.equals(rect))return;
			_textInnerRect = rect;
			onPropertiesChanged(P_textInnerRect);
		}
		/**
		 * 
		 * @param rect 用于定位选中信息的文本的Rectangle的信息的字符串
		 * 
		 */
		public function set textInnerRectString(rectvalue:String):void
		{
			if(_textRectString == rectvalue)return;
			_textRectString = rectvalue;
			textInnerRect = ClassUtils.CreatInstance(ClassUtils.INNERRECTANGLE,ComponentFactory.parasArgs(_textRectString));
		}
		/**
		 * 
		 * @param stylename 用于选中信息的文本的样式
		 * 通过ComponentFactory创建
		 * 
		 */		
		public function set textStyle(stylename:String):void
		{
			if(_textStyle == stylename)return;
			_textStyle = stylename;
			textField = ComponentFactory.Instance.creat(_textStyle);
		}
		
		protected function __onItemChanged(event:ListItemEvent):void
		{
			_currentSelectedItem = event.cell;
			_currentSelectedCellValue = event.cellValue;
			_currentSelectedIndex =  event.index;
			if(_selctedPropName != null)_textField.text = event.cell[_selctedPropName];
			dispatchEvent(new InteractiveEvent(InteractiveEvent.STATE_CHANGED));
		}
		
		override protected function addChildren():void
		{
			super.addChildren();
			if(_button)addChild(_button);
			if(_textField)addChild(_textField);
		}
		
		override protected function init():void
		{
			_maskShape = new Shape();
			addEventListener(Event.ADDED_TO_STAGE,__onAddToStage);
			StageReferance.stage.addEventListener(MouseEvent.CLICK,__onStageClick);
			StageReferance.stage.addEventListener(MouseEvent.MOUSE_DOWN,__onStageDown);
			super.init();
		}

		protected function __onStageClick(event:MouseEvent):void
		{
			var target:DisplayObject = event.target as DisplayObject;
			if(!DisplayUtils.isTargetOrContain(target,this) && !DisplayUtils.isTargetOrContain(target,_listPanel))return;
			if(DisplayUtils.isTargetOrContain(target,_button) || DisplayUtils.isTargetOrContain(target,_listPanel.list))
			{
				if(_state == HIDE)
				{
					doShow();
				}else
				{
					doHide();
				}
			}
		}
		
		protected function __onStageDown(event:MouseEvent):void
		{
			var target:DisplayObject = event.target as DisplayObject;
			if(DisplayUtils.isTargetOrContain(target,_listPanel) || DisplayUtils.isTargetOrContain(target,this))return;
			doHide();
		}
		
		protected function onHideComplete():void
		{
			if(_listPanel && _listPanel.parent)_listPanel.parent.removeChild(_listPanel.asDisplayObject());
			if(_maskShape && _maskShape.parent)_maskShape.parent.removeChild(_maskShape);
		}
		
		override protected function onPosChanged():void
		{
			_comboboxZeroPos = DisplayUtils.getPointFromObject(new Point(0,0),this,ComponentSetting.COMBOX_LIST_LAYER);
			updateListPos();
			updateMask();
		}
		
		override protected function onProppertiesUpdate():void
		{
			super.onProppertiesUpdate();
			if(_changedPropeties[P_listInnerRect] || _changedPropeties[Component.P_height] 
				|| _changedPropeties[Component.P_width] || _changedPropeties[P_defaultShowState] 
				|| _changedPropeties[P_listPanel])
			{
				onPosChanged();
				updateListSize();
				if(_listPanel)_listPanel.list.addStateListener(updateListSize);
			}
			
			if(_changedPropeties[P_textInnerRect] || _changedPropeties[Component.P_height] || _changedPropeties[Component.P_width])
			{
				DisplayUtils.layoutDisplayWithInnerRect(_textField,_textInnerRect,_width,_height);
			}
			
			if(_changedPropeties[Component.P_height] || _changedPropeties[Component.P_width])
			{
				_button.beginChanges();
				_button.width = _width;
				_button.height = _height;
				_button.commitChanges();
			}
		}
		
		protected function updateListPos():void
		{
			if(_listInnerRect == null || _listPanel == null)return;
			var listRect:Rectangle = _listInnerRect.getInnerRect(_width,_height);
			_listPanel.x = _comboboxZeroPos.x+listRect.x;
			_listPanel.y = _comboboxZeroPos.y+listRect.y;
			if(_defaultShowState == COMBOX_HIDE_STATE)
			{
				_listPanel.y =  _comboboxZeroPos.y - _listPanel.height;
			}else if(_defaultShowState == COMBOX_SHOW_STATE)
			{
				_listPanel.y = _comboboxZeroPos.y + _listInnerRect.para2;
			}
		}
		
		protected function updateListSize(event:InteractiveEvent = null):void
		{
			if(_listPanel == null)return;
			var listRect:Rectangle = _listInnerRect.getInnerRect(_width,_height);
			if(_snapItemHeight)
			{
				_listPanel.height = _listPanel.list.getViewSize().height+_listPanel.getShowHScrollbarExtendHeight();
			}else
			{
				_listPanel.height = listRect.height;
			}
			_listPanel.width = listRect.width;
			_maskShape = DisplayUtils.drawRectShape(_listPanel.width+2*_maskExtends,_listPanel.height+_maskExtends*2,_maskShape);
			updateMask();
		}
		
		protected function updateMask():void
		{
			if(!_listPanel)return;
			_listPanel.mask = _maskShape;
			_maskShape.x = _comboboxZeroPos.x - _maskExtends;
			_maskShape.y = _comboboxZeroPos.y + _height;
		}
		
		public static const P_snapItemHeight:String = "snapItemHeight";
		protected var _snapItemHeight:Boolean;
		public function set snapItemHeight(value:Boolean):void
		{
			if(_snapItemHeight == value)return;
			_snapItemHeight = value;
			onPropertiesChanged(P_snapItemHeight);
		}

		protected function __onAddToStage(event:Event):void
		{
			onPosChanged();
		}
	}
}